package cn.maiyar.dingding.service;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import cn.maiyar.dingding.DingDingProperties;
import cn.maiyar.dingding.entity.DingDingText;
import cn.maiyar.dingding.entity.DingDingTextNotification;
import cn.maiyar.dingding.entity.DingDingResult;
import cn.maiyar.dingding.feign.IDingDingClient;
import cn.maiyar.dingding.menu.DingDingTextType;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Base64Utils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * 钉钉通知服务
 *
 * @author c.c
 */
@Slf4j
@Setter
public class DingDingService implements IDingDingClient {

    private DingDingProperties dingDingProperties;

    public DingDingService(DingDingProperties dingDingProperties) {
        this.dingDingProperties = dingDingProperties;
    }

    /**
     * 发送钉钉消息
     *
     * @param data 消息内容
     * @return
     */
    @Override
    public DingDingResult doSend(String data) {
        boolean enabled = dingDingProperties.isEnabled();
        if (!enabled) {
            return new DingDingResult();
        }
        String webhook = dingDingProperties.getRobot();
        String secret = dingDingProperties.getSecret();
        boolean enableSignatureCheck = dingDingProperties.isEnableSignatureCheck();
        if (enableSignatureCheck && StrUtil.isNotEmpty(secret)) {
            long timestamp = System.currentTimeMillis();
            String stringToSign = timestamp + "\n" + secret;
            Mac mac;
            try {
                mac = Mac.getInstance("HmacSHA256");
                SecretKeySpec hmacSHA256 = new SecretKeySpec(secret.getBytes(Charset.defaultCharset()), "HmacSHA256");
                mac.init(hmacSHA256);
                byte[] signData = mac.doFinal(stringToSign.getBytes(Charset.defaultCharset()));
                String sign = URLEncoder.encode(new String(Base64Utils.encode(signData)), StandardCharsets.UTF_8);
                webhook += "&timestamp=" + timestamp + "&sign=" + sign;
            } catch (NoSuchAlgorithmException | InvalidKeyException e) {
                log.warn("钉钉推送异常!", e);
            }
        }
        DingDingTextType dingdingTextType = dingDingProperties.getDingdingTextType();
        switch (dingdingTextType) {
            case TEXT:
                DingDingText dingDingText = new DingDingText();
                dingDingText.setContent(data);
                DingDingTextNotification notification = new DingDingTextNotification();
                notification.setMsgtype("text");
                notification.setText(dingDingText);
                data = JSONUtil.toJsonStr(notification);
                break;
            case MARKDOWN:
            default:
                // 暂不处理
                break;
        }
        String body = HttpRequest.post(webhook)
                .header("Content-Type", "application/json")
                .body(data, "application/json")
                .execute()
                .body();

        return JSONUtil.toBean(body, DingDingResult.class);
    }
}
